#ifndef DATACENTER_H
#define DATACENTER_H

#include <QObject>
#include "data.h"
#include "../network/netclient.h"

namespace model
{

/**********************************************************************************************
 * 当前客户端用户的所有信息
 **********************************************************************************************/
    class DataCenter : public QObject
    {
        Q_OBJECT
    public:
        static DataCenter* getInstance();

        //初始化持久化文件
        void initDataFile();
        //将数据持久化
        void saveDataToFile();
        //读取已持久化的数据
        void loadDataFromFile();

        void initWebSocket();

        QString getLoginSessionId()
        {
            return loginSessionId;
        }

        //依据会话id,查找对应的会话信息
        ChatSessionInfo* findChatSessionById(const QString& chatSessionId);
        //设置当前的会话Id
        void setCurrentChatSessionId(const QString& chatSessionId) {currentSessionId = chatSessionId;}
        //根据Id，查找对应的会话列表
        ChatSessionInfo* findChatSessionByUserId(const QString& userId);
        //将会话置顶
        void topChatSessionInfo(const ChatSessionInfo& chatSessionInfo);
        void addMessage(const MessageInfo& message);

        //清空未读消息数目
        void clearUnread(const QString& chatSessionId);
        //增加未读消息数目
        void addUnread(const QString& chatSessionId);
        //获取未读消息述目
        int getUnread(const QString& chatSessionId);

    public:
        //网络通信相关
        void pingHttp()
        {
            netClient.pingHttp();
        }

        //网络获取
        void getMyselfAsync();
        //通过智能指针，减少拷贝
        void resetMyself(std::shared_ptr<my::GetUserInfoRsp> pbResp);
        //本地获取，进行设置
        UserInfo* getMyself() { return myself; }

        void getFriendListAsync();
        void resetFriendList(std::shared_ptr<my::GetFriendListRsp> pbResp);
        QList<UserInfo>* getFriendList(){return friendList;}

        void getChatSessionListAsync();
        void resetChatSessionLIst(std::shared_ptr<my::GetChatSessionListRsp> pbResp);
        QList<ChatSessionInfo>* getChatSessionList() { return chatSessionList; }

        void getApplyListAsync();
        void resetApplyList(std::shared_ptr<my::GetPendingFriendEventListRsp> pbResp);
        QList<UserInfo>* getApplyList() { return applyList; }


        void getRecentMessageAsync(const QString& chatSessionId,bool updateUi);
        void resetRecentMessageList(const QString& chatSessionId,std::shared_ptr<my::GetRecentMsgRsp> pbResp);
        QList<MessageInfo>* getRecentMessageList(const QString& chatSessionId);

        //获取当前的会话Id
        QString getCurrentSessionId() { return currentSessionId;}
        void sendTextMessageAsync(const QString& chatSessionId,const QString& content);

        //修改名称
        void ChangeNickNameAsync(const QString& nickName);
        void resetNickName(const QString& nickName);

        //修改签名
        void ChangeDescAscyc(const QString& desc);
        void resetDesc(const QString& desc);

        //获取验证码
        void getVerifycodeAsync(const QString& phone);
        //设置服务器返回的验证码对应的ID
        void resetVerifyCodeId(const QString& verifyCodeId);
        QString getVerigyCodeId() { return currentVerifyId;}

        //修改手机号
        void changePhoneAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
        void resetPhone(const QString& phone);

        //修改头像
        void changeAvatarAsync(const QByteArray& imageBytes);
        void resetAvatar(const QByteArray& avatar);

        UserInfo* findFriendById(const QString& userId);

        //删除好友
        void deleteFriendAsync(const QString& userId);
        void removeFriend(const QString userId);

        //添加好友
        void applyFriendAsync(const QString& userId);

        //同意好友申请
        void agreeFriendApplyAsync(const QString& userId);
        void rejectFriendApplyAsync(const QString& userId);
        //删除好友申请列表中的指定内容
        UserInfo removeFriendApply(const QString& userId);
        //创建群聊
        void  createGroupChatSessionAsync(const QList<QString>& userIdList);
        QString getCurrentChatSessionId(){return currentSessionId;}

        //获取群聊会话成员列表
        void getMemberListAsync(const QString& currentSessionId);
        void resetMemberList(const QString& chatSessionID,const QList<my::UserInfo>& memberList);
        QList<UserInfo>* getMemberList(const QString& chatSessionID);

        //搜索用户
        void searchUserAsync(const QString& searchKay);
        void resetSearchUserResult(const QList<my::UserInfo>& userList);
        QList<UserInfo>* getSearchUserResult();

        //搜索消息
        void getHistoryMessageByKeyAsync(const QString& searchKey);
        void getHistoryMessageByTimeAsync(const QDateTime& beginTime,const QDateTime& endTime);
        void resetSearchHistoryMessageList(const QList<my::MessageInfo>& messageList);
        QList<MessageInfo>* getSearchMessageResult();

        //用户登录
        void userLoginAsync(const QString& userName,const QString& password);
        void resetLoginId(const QString& loginSessionId);

        //用户注册
        void userRegisterAsync(const QString& userName,const QString& password);

        //手机登录
        void phoneLoginAsync(const QString& phone,const QString& verifyCode);
        void phoneRegisterAsync(const QString& phone,const QString& verifyCode);

        //一个单独从服务器获取"文件(图片、文件、语音)"的接口
        void getSingleFileAsync(const QString& fileId);

        //发送图片消息
        void sendImageMessageAsync(const QString& chatSessionId,const QByteArray& imageContent);

        //发送文件消息
        void sendFileMessageAsync(const QString& chatSessionId,const QString& fileName,const QByteArray& fileContent);

        //发送语音消息
        void sendSpeechMessageAsync(const QString& chatSessionId,const QByteArray& speechContent);

        //语音转文字
        void speechConvertTextAsync(const QString& fileId,const QByteArray& speechContent);
    private:
        DataCenter();
        ~DataCenter();
        static DataCenter* instance;

        QString loginSessionId;                  //登录会话Id(目的：客户端重启后，不必重新登录)
        QString currentVerifyId;                                //短信验证码的验证Id
        QString currentSessionId;                               //当前的会话ID
        UserInfo* myself = nullptr;                             //当前用户的信息
        QList<UserInfo>* friendList = nullptr;                  //好友列表
        QList<ChatSessionInfo>* chatSessionList = nullptr;      //会话列表
        QList<UserInfo>* applyList = nullptr;                   //待处理的好友申请列表
        QHash<QString,int>* unReadMessageCount = nullptr;       //每个会话未读消息的个数
        QList<UserInfo>* searchFriendList = nullptr;            //用户的好友搜索记录(当前搜索)
        QList<MessageInfo>* searchMessageList = nullptr;        //历史消息搜索记录
        QHash<QString,QList<UserInfo>>* memberList = nullptr;   //记录每个会话中有哪些成员(针对群聊)，key为ChatSessionInfo.chatSessionId
        QHash<QString,QList<MessageInfo>>* recentMessage = nullptr;//每个会话最近的消息列表，key为ChatSessionInfo.chatSessionId

    private:
        //让dataCenter持有NetClient实例
        network::NetClient netClient;

    signals:
        //自定义信号
        void getMyselfDone();
        void getFriendListDone();
        void getChatSessionListDone();
        void getAppalListDone();
        void getRecentMessageDone(const QString& chatSessionId);
        void getRecentMessageDoneNoUi(const QString& chatSessionId);
        void sendMessageDone(MessageType messageType, const QByteArray& content, const QString& extraInfo);
        void updateLastMessage(const QString& chatSessionId);

        void receiveMessageDone(const MessageInfo& lastMessage);
        void changeNickNameDone();
        void changeDescDone();
        void getVerifyCodeDone();
        void changePhoneDone();
        void changeAvatarDone();
        void clearCurrentSession();
        void deleteFriendDone();
        void applyFriendDone();
        void receiveFriendApplyDone();
        void agreeFriendApplyDone();
        void rejectFriendApplyDone();
        void recevieFriendApplyProcessDone(const QString& userName,bool agree);
        void createGroupChatSessionDone();
        void receiveSessionCreateDone();
        void getMemberListDone(const QString& chatSessionId);
        void searchUserDone();
        void searchMessageDone();
        void userLoginDone(const bool ok,const QString reason);
        void userRegisterDone(const bool ok,const QString reason);
        void phoneLoginDone(const bool ok,const QString reason);
        void phoneRegisterDone(const bool ok,const QString reason);
        void getSingleFileDone(const QString& fileId,const QByteArray& fileContent);
        void speechConvertTextDone(const QString& fileId,const QString& speechContent);
    };
} //end namespace

#endif // DATACENTER_H
